﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using gbL.NetBoard.Helpers;

namespace gbL.NetBoard.Tests
{
    [TestFixture]
    public class MultiTypedMessageListenerTests
    {
        private class GreetingEnglish { public string Text { get; set; } }

        private class GreetingFrench { public string Text { get; set; } }

        private class GreetingKlingon { public string Text { get; set; } }

        private class GreetingListener : MultiTypedMessageListener
        {
            public GreetingListener(Blackboard domain)
                : base(domain)
            {
                Added = new List<object>();
                Removed = new List<object>();
            }

            public List<object> Added { get; set; }

            public List<object> Removed { get; set; }

            protected override Type[] MessageTypes
            {
                get { return new[] { typeof(GreetingEnglish), typeof(GreetingFrench) }; }
            }

            protected override void OnMessageAdded(object message)
            {
                Added.Add(message);
            }

            protected override void OnMessageRemoved(object message)
            {
                Removed.Add(message);
            }
        }

        [Test]
        public void Should_receive_GreetingEnglish()
        {
            // A
            Blackboard domain = new Blackboard();
            GreetingListener listener = new GreetingListener(domain);
            GreetingEnglish greeting = new GreetingEnglish();
            // A
            domain.Add(greeting);
            // A
            Assert.That(listener.Added, Has.Count.EqualTo(1));
        }

        [Test]
        public void Should_receive_GreetingFrench()
        {
            // A
            Blackboard domain = new Blackboard();
            GreetingListener listener = new GreetingListener(domain);
            GreetingFrench greeting = new GreetingFrench();
            // A
            domain.Add(greeting);
            // A
            Assert.That(listener.Added, Has.Count.EqualTo(1));
        }

        [Test]
        public void Should_not_receive_GreetingKlingon()
        {
            // A
            Blackboard domain = new Blackboard();
            GreetingListener listener = new GreetingListener(domain);
            GreetingKlingon greeting = new GreetingKlingon();
            // A
            domain.Add(greeting);
            // A
            Assert.That(listener.Added, Has.Count.EqualTo(0));
        }

        [Test]
        public void Should_receive_GreetingEnglish_removed()
        {
            // A
            Blackboard domain = new Blackboard();
            GreetingListener listener = new GreetingListener(domain);
            GreetingEnglish greeting = new GreetingEnglish();
            domain.Add(greeting);
            // A
            domain.Take(e => e.Message == greeting);
            // A
            Assert.That(listener.Removed, Has.Count.EqualTo(1));
        }

        [Test]
        public void Should_receive_GreetingFrench_removed()
        {
            // A
            Blackboard domain = new Blackboard();
            GreetingListener listener = new GreetingListener(domain);
            GreetingFrench greeting = new GreetingFrench();
            domain.Add(greeting);
            // A
            domain.Take(e => e.Message == greeting);
            // A
            Assert.That(listener.Removed, Has.Count.EqualTo(1));
        }

        [Test]
        public void Should_not_receive_GreetingKlingon_removed()
        {
            // A
            Blackboard domain = new Blackboard();
            GreetingListener listener = new GreetingListener(domain);
            GreetingKlingon greeting = new GreetingKlingon();
            domain.Add(greeting);
            // A
            domain.Take(e => e.Message == greeting);
            // A
            Assert.That(listener.Removed, Has.Count.EqualTo(0));
        }
    }
}
